package org.apache.shenyu.plugin.cryptor.strategy;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.spec.IvParameterSpec;
import java.util.Base64;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Random;

public class AESStrategy implements CryptorStrategy{
    @Override
    public String decrypt(String key, byte[] msg) throws Exception {
        try {
            byte[] cipherbytes = Base64.getDecoder().decode(new String(msg,"UTF-8"));
            byte[] initVector = Arrays.copyOfRange(cipherbytes, 0, 16);
            byte[] messagebytes = Arrays.copyOfRange(cipherbytes, 16, cipherbytes.length);
            IvParameterSpec iv = new IvParameterSpec(initVector);
            SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
            cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
            byte[] byte_array = cipher.doFinal(messagebytes);
            return new String(byte_array, StandardCharsets.UTF_8);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }
    @Override
    public String encrypt(String key, String plaintext) throws Exception {
        try {
            // Generate a random 16-byte initialization vector
            byte initVector[] = new byte[16];
            (new Random()).nextBytes(initVector);
            IvParameterSpec iv = new IvParameterSpec(initVector);
            // prep the key
            SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
            // prep the AES Cipher
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
            // Encode the plaintext as array of Bytes
            byte[] cipherbytes = cipher.doFinal(plaintext.getBytes());
            // Build the output message initVector + cipherbytes -> base64
            byte[] messagebytes = new byte[initVector.length + cipherbytes.length];
            System.arraycopy(initVector, 0, messagebytes, 0, 16);
            System.arraycopy(cipherbytes, 0, messagebytes, 16, cipherbytes.length);
            return Base64.getEncoder().encodeToString(messagebytes);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

//    public static void main(String[] args) throws Exception {
//        String aa = "测试的@!@!$";
//        AESStrategy aes = new AESStrategy();
//        aa = aes.encrypt("0123456789123456",aa);
//        System.out.println(aa);
//        System.out.println(aes.decrypt("0123456789123456",aa.getBytes(StandardCharsets.UTF_8)));
//    }
}
